package com.youlai.system.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.youlai.common.base.BaseServiceImpl;
import com.youlai.common.exception.BusinessException;
import com.youlai.common.model.Option;
import com.youlai.common.result.PageResult;
import com.youlai.common.result.ResultCode;
import com.youlai.utils.DateUtils;
import com.youlai.utils.IdWorker;
import com.youlai.core.mybatisplus.handler.WrappersFactory;
import com.youlai.system.mapper.SysOrgMapper;
import com.youlai.system.model.entity.SysDict;
import com.youlai.system.entity.SysOrgEntity;
import com.youlai.system.model.entity.SysUser;
import com.youlai.system.model.query.OrgPageQuery;
import com.youlai.system.service.SysDictService;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据字典项业务实现类
 *
 * @author xiamw
 * @since 2024/01/12
 */
@Service
@RequiredArgsConstructor
public class SysOrgService extends BaseServiceImpl<SysOrgMapper, SysOrgEntity> {

    @Resource
    SysDictService sysDictService;

    /**
     * 分页查询列表
     *
     * @param queryParams
     * @return
     */
    public PageResult<SysOrgEntity> queryPage(OrgPageQuery queryParams) {
        // 查询参数
        String keywords = queryParams.getKeywords();

        // 格式化为数据库日期格式，避免日期比较使用格式化函数导致索引失效
        DateUtils.toDatabaseFormat(queryParams, "startUpdateTime", "endUpdateTime");

        Integer pageSize = queryParams.getPageSize();
        if (pageSize != null) {
            int current =  queryParams.getPageNum();
            int offset = pageSize * (current-1);

            long totalCount = this.baseMapper.queryPageCount(queryParams);
            if (totalCount > 0) {
                if (offset >= totalCount) {
                    offset = offset - pageSize;
                }
                if(offset<0) {
                    offset=0;
                }
                RowBounds rowBounds = new RowBounds(offset, pageSize);
                List<SysOrgEntity> list = this.baseMapper.queryPage(queryParams,rowBounds);

                // 数据字典项
                List<SysDict> dictList = sysDictService.list(new LambdaQueryWrapper<SysDict>()
                        .eq(SysDict::getTypeCode, "orgType")
                        .select(SysDict::getValue, SysDict::getName)
                );
                Map<String,String> orgTypeMap =  dictList.stream().collect(Collectors.toMap(SysDict::getValue,SysDict::getName));

                for(SysOrgEntity o:list) {
                    o.setOrgTypeName(orgTypeMap.get(String.valueOf(o.getOrgType())));
                }
                //赋值
                return PageResult.success(list,totalCount);
            } else {
                return PageResult.success(new  ArrayList<SysOrgEntity>(),0);
            }
        } else {
            RowBounds rowBounds = new RowBounds(0, 1000);
            List<SysOrgEntity> list = this.baseMapper.queryPage(queryParams,rowBounds);
            return PageResult.success(list,1000l);
        }
    }

    /**
     * 分页查询列表
     *
     * @param queryParams
     * @return
     */
    public Page<SysOrgEntity> getPage(OrgPageQuery queryParams) {
        // 查询参数
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        String keywords = queryParams.getKeywords();

        // 格式化为数据库日期格式，避免日期比较使用格式化函数导致索引失效
        DateUtils.toDatabaseFormat(queryParams, "startUpdateTime", "endUpdateTime");

        // 查询数据
        Page<SysOrgEntity> pageResult =  this.baseMapper.selectJoinPage(new Page<>(pageNum, pageSize), SysOrgEntity.class, new MPJLambdaWrapper<SysOrgEntity>()
                .selectAll(SysOrgEntity.class)
                .selectAs(SysUser::getUsername, SysOrgEntity::getUpdateName)
                .leftJoin(SysUser.class, SysUser::getId, SysOrgEntity::getUpdateBy)
                .and(StrUtil.isNotBlank(keywords),
                        wrapper ->
                                wrapper.like(StrUtil.isNotBlank(keywords), SysOrgEntity::getOrgName, keywords)
                                        .or()
                                        .like(StrUtil.isNotBlank(keywords), SysOrgEntity::getOrgCode, keywords)
                )
                .ge(StrUtil.isNotBlank(queryParams.getStartUpdateTime()), SysOrgEntity::getUpdateTime, queryParams.getStartUpdateTime())
                .le(StrUtil.isNotBlank(queryParams.getEndUpdateTime()), SysOrgEntity::getUpdateTime, queryParams.getEndUpdateTime())
                .orderByDesc(SysOrgEntity::getUpdateTime));
        List<SysOrgEntity> list = pageResult.getRecords();

        // 数据字典项
        List<SysDict> dictList = sysDictService.list(new LambdaQueryWrapper<SysDict>()
                .eq(SysDict::getTypeCode, "orgType")
                .select(SysDict::getValue, SysDict::getName)
        );
        Map<String,String> orgTypeMap =  dictList.stream().collect(Collectors.toMap(SysDict::getValue,SysDict::getName));

        for(SysOrgEntity o:list) {
            //o.setOrgTypeName(IBaseEnum.getLabelByValue(o.getOrgType(), com.youlai.system.common.enums.GenderEnum.class));
            o.setOrgTypeName(orgTypeMap.get(String.valueOf(o.getOrgType())));
        }

        return pageResult;
    }

    /**
     * 新增字典数据项
     *
     * @param entity 字典数据项表单
     * @return
     */
    public boolean saveOrUpdate(SysOrgEntity entity) {
        boolean result = false;
        if(entity.getOrgId()==null) {
            Long cnt = this.count(new LambdaQueryWrapper<SysOrgEntity>()
                    .eq(SysOrgEntity::getOrgCode,entity.getOrgCode()));
            if(cnt>0) {
                throw new BusinessException(ResultCode.REPEAT_CODE_ERROR);
            }
            entity.setOrgId(IdWorker.generateId());
            result = this.save(entity);
        }else {
            Long id = entity.getOrgId();
            Long cnt = this.count(new LambdaQueryWrapper<SysOrgEntity>()
                    .ne(SysOrgEntity::getOrgId, id)
                    .eq(SysOrgEntity::getOrgCode,entity.getOrgCode()));
            if(cnt>0) {
                throw new BusinessException(ResultCode.REPEAT_CODE_ERROR);
            }
            result = this.update(WrappersFactory.updateWithNullField(entity).eq(SysOrgEntity::getOrgId,id));
        }
        return result;
    }

    /**
     * 字典数据项表单详情
     *
     * @param id 字典数据项ID
     * @return
     */
    public SysOrgEntity getForm(Long id) {
        // 获取entity
        SysOrgEntity entity = this.getOne(new LambdaQueryWrapper<SysOrgEntity>()
                .eq(SysOrgEntity::getOrgId, id));
        Assert.isTrue(entity != null, "数据项不存在");
        return entity;
    }

    /**
     * 字典数据项表单详情
     *
     * @param entity 字典数据项ID
     * @return
     */
    public List<SysOrgEntity> getList(SysOrgEntity entity) {
        List<SysOrgEntity> list =  this.baseMapper.selectJoinList(SysOrgEntity.class, new MPJLambdaWrapper<SysOrgEntity>()
                .selectAll(SysOrgEntity.class)
                .selectAs(SysUser::getUsername, SysOrgEntity::getUpdateName)
                .leftJoin(SysUser.class, SysUser::getId, SysOrgEntity::getUpdateBy)
                .eq(entity.getOrgId()!=null, SysOrgEntity::getOrgId, entity.getOrgId())
                .eq(StringUtils.isNotEmpty(entity.getOrgCode()),SysOrgEntity::getOrgCode, entity.getOrgCode())
                .orderByDesc(SysOrgEntity::getUpdateTime));
        return list;
    }

    /**
     * 字典数据项表单详情
     *
     * @param entity 字典数据项ID
     * @return
     */
    public List<SysOrgEntity> queryList(SysOrgEntity entity) {
        List<SysOrgEntity> list =  this.baseMapper.queryList(entity);
        return list;
    }

    /**
     * 删除字典数据项
     *
     * @param idsStr 字典数据项ID，多个以英文逗号(,)分割
     * @return
     */
    public boolean deleteByIds(String idsStr) {
        Assert.isTrue(StrUtil.isNotBlank(idsStr), "删除数据为空");
        //
        List<Long> ids = Arrays.asList(idsStr.split(","))
                .stream()
                .map(id -> Long.parseLong(id))
                .collect(Collectors.toList());

        boolean result = this.removeByIds(ids);
        return result;
    }

    /**
     * 获取字典下拉列表
     *
     * @param typeCode
     * @return
     */
    public List<Option> listDictOptions(String typeCode) {
        // 数据字典项
        List<SysDict> dictList = sysDictService.list(new LambdaQueryWrapper<SysDict>()
                .select(SysDict::getValue, SysDict::getName)
                .eq(SysDict::getTypeCode, typeCode)
        );

        // 转换下拉数据
        List<Option> options = CollectionUtil.emptyIfNull(dictList)
                .stream()
                .map(dictItem -> new Option(dictItem.getValue(), dictItem.getName()))
                .collect(Collectors.toList());
        return options;
    }
}




